import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.locks.LockSupport;

//是想定时任务
public class ScheduleService {
    Trigger trigger = new Trigger();

    ExecutorService executorService = Executors.newFixedThreadPool(6);
    public void schedule(Runnable task, long delay) {
        Job job = new Job();
        job.setTask(task);
        job.setStartTime(System.currentTimeMillis() + delay);
        job.setDelay(delay);
        trigger.queue.offer(job);
        trigger.wakeUp();
    }

    //等待合适时间，把对应的任务丢入线程池中运行
    class Trigger{
        PriorityBlockingQueue<Job> queue = new PriorityBlockingQueue<>();
        Thread thread = new Thread(()->{
            while(true) {
//                if(queue.isEmpty()){
//                    LockSupport.park();
//                }
                //线程wait唤醒有三种方法，notify,wait等待时间到了,线程中断
                //还有一种虚假唤醒，此时队列空，出现空指针异常，避免这个问题，推荐使用while
                while(queue.isEmpty()){
                    LockSupport.park();
                }
                Job latelyJob = queue.peek();//peek和poll的区别拿到最新的任务，但peek不会移除任务
                if(latelyJob.getStartTime() < System.currentTimeMillis()){
                    //多线程环境下
                    latelyJob = queue.poll();
                    executorService.execute( latelyJob.getTask());
                    Job nextJob = new Job();
                    nextJob.setTask(latelyJob.getTask());
                    nextJob.setDelay(latelyJob.getDelay());
                    nextJob.setStartTime(System.currentTimeMillis() + latelyJob.getDelay());
                    queue.offer(nextJob);

                }else{
                    LockSupport.parkUntil(latelyJob.getStartTime());
                }
//                if(!queue.isEmpty()){
//                    Job job = queue.poll();
//                    long waitTime = job.getStartTime() - System.currentTimeMillis();
//                    if(waitTime > 0){
//                        LockSupport.park(1);
//                    }
//                    executorService.execute( job.getTask());
//                }

            }
        });
        {
            thread.start();
            System.out.println("trigger start");
        }



        void wakeUp(){
            LockSupport.unpark(thread);
        }


    }



}
